#include "graphitemobject.h"
#include <QDir>

GraphItemObject::GraphItemObject(QGraphicsItem *parent)
    : QGraphicsObject{parent}
{
    this->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
    m_color = Qt::transparent;
    pixels_width = 0;
    mult_x = 0;
    mult_y = 0;
    shift_x = 0;
    shift_y = 0;
    m_paintCount=0;
    cell_size = 20;
}

QRectF GraphItemObject::boundingRect() const
{
    return {0, 0, 1100, 350};
}

void GraphItemObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{

    auto t1 = std::chrono::steady_clock::now();
    if(not m_paintCount)
        updatePoints();
    painter->save();
    QPen pen_test(Qt::red);
    painter->setPen(pen_test);

    for(int i = 0; i < boundingRect().width() - cell_size; i++)
    {
        if(i and max_values[i - 1] < min_values[i])
        {
            painter->drawLine(QPoint(i - 1 + cell_size, max_values[i - 1] * mult_y + shift_y), QPoint(i + cell_size, min_values[i] * mult_y + shift_y));
        }
        else if(i and min_values[i - 1] > max_values[i])
        {
            painter->drawLine(QPoint(i - 1 + cell_size, min_values[i - 1] * mult_y + shift_y), QPoint(i + cell_size, max_values[i] * mult_y + shift_y));
        }
        // Закрашиваем сектор с минимума по максимум
        painter->drawLine(QPoint(i + cell_size, max_values[i] * mult_y + shift_y), QPoint(i + cell_size, min_values[i] * mult_y + shift_y));

    }
    QPen pen2(Qt::black);
    pen2.setStyle(Qt::DotLine);
    painter->setPen(pen2);
    painter->setFont(QFont("Arial", 5));
    for (double x = cell_size * 3; x <= pixels_width; x += cell_size * 3)
    {
        painter->drawText(x - cell_size, boundingRect().height(), QString::number((x - shift_x) / mult_x));
        painter->drawLine(x, cell_size, x, boundingRect().height());
        //painter.drawPoint(x, ui->pixmapLabel->height() - cell_size);
    }
    for (double y = boundingRect().height() - cell_size; y > cell_size; y -= cell_size)
    {
        painter->drawText(0, y, QString::number((y - shift_y) / mult_y));
        painter->drawLine(cell_size, y, boundingRect().width(), y);
    }

    // Закрашиваем пиксели с точками
    QPen pen3(Qt::blue);
    painter->setPen(pen3);
    for(int i = 0; i < points.size(); i++)
    {
        for(int j = 0; j < points[i].size(); j++)
        {
            if(points[i][j])
                painter->drawPoint(i + cell_size, j);
        }
    }
    painter->restore();
    m_paintCount++;
    auto t2 = std::chrono::steady_clock::now() - t1;
    qDebug() << "paint time " << std::chrono::duration_cast<std::chrono::milliseconds>(t2).count() << " ms";
}

void GraphItemObject::updatePoints()
{
    //read 370
    auto t1 = std::chrono::steady_clock::now();
    qDebug() << QDir::currentPath();
    //MERA mera(0,"/home/student/alekseev_pfoject/alekseev_semen/test/test_R/test.mera");
    MERA mera(0, QDir::currentPath() + "/test_R/test.mera");
    if(mera.load())
        if(mera.paramList().size()){
            qDebug() << mera.paramList().first()->open_only(QIODevice::ReadOnly);  //readDat
        }
    pixels_width = boundingRect().width() - cell_size;
    int values_count = mera.paramList().first()->unread_size() / sizeof(double);
    qDebug() << values_count;
    int points_in_pixel = values_count / (pixels_width - 1);
    int glob_min = 0;
    int glob_max = 0;
    if(values_count % (pixels_width - 1) == 0)
    {
        pixels_width--;
    }
    // В каждый пиксель нельзя отобразить более одной точки, поэтому поделим поле на кол-во секторов(на колонки), равное кол-ву пикселей в ширину
    // Для каждого сектора есть соответствующий элемент в каждом из 4 массивов
    max_values.resize(pixels_width);
    min_values.resize(pixels_width);
    points.resize(pixels_width);

    vector<double> group(points_in_pixel);  // Здесь будут храниться все значения текущего сектора

    for(int i = 0, uncalc_values = values_count - points_in_pixel; i < pixels_width; i++, uncalc_values -= points_in_pixel)
    {
        int group_count = points_in_pixel;
        if(uncalc_values < 0)
        {
            group_count += uncalc_values;
        }
        mera.paramList().first()->tx()->calc_poly_part(&group, group_count);
        max_values[i] = group[0];
        min_values[i] = group[0];
        if(not i)
        {
            glob_min = group[0];
            glob_max = group[0];
        }
        for (int j = 0; j < group_count; j++)
        {
            if(max_values[i] < group[j])
            {
                max_values[i] = group[j];
                if(glob_min < group[j])
                {
                    glob_min = group[j];
                }
            }
            if(min_values[i] > group[j])
            {
                min_values[i] = group[j];
                if(glob_max > group[j])
                {
                    glob_max = group[j];
                }
            }
        }
    }
    double diff = glob_max - glob_min;
    glob_max += diff / cell_size;
    glob_min -= diff / cell_size;
    double y_length = glob_max - glob_min;
    double x_length = values_count - 1;
    if (y_length == 0)
    {
        y_length = 1;
    }
    // Переменные для перевода вещественного значения в координаты пикселя
    mult_x = (boundingRect().width() - cell_size) / x_length;
    mult_y = boundingRect().height() / y_length;
    shift_x = cell_size;
    shift_y = -glob_min * mult_y;
    if(mera.load())
        if(mera.paramList().size()){
            qDebug() << mera.paramList().first()->open_only(QIODevice::ReadOnly);  //readDat
        }

    // Определяем в каких пикселях будут точки
    for(int i = 0, uncalc_values = values_count - points_in_pixel; i < pixels_width; i++, uncalc_values -= points_in_pixel)
    {
        int group_count = points_in_pixel;
        if(uncalc_values < 0)
        {
            group_count += uncalc_values;
        }
        mera.paramList().first()->tx()->calc_poly_part(&group, group_count);
        points[i] = vector<bool>(boundingRect().height());
        for (int j = 0; j < group_count; j++)
        {
            points[i][group[j] * mult_y + shift_y] = true;
        }
    }
    group.clear();
    auto t2 = std::chrono::steady_clock::now() - t1;
    qDebug() << "calc_paint time " << std::chrono::duration_cast<std::chrono::milliseconds>(t2).count() << " ms";
}

void GraphItemObject::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
        qDebug() << event->pos();

        m_color = Qt::green;
}
